Reset the focused element when a frame loses document focus Resetting focus would also clear selection on editable element, so get current selected text before moving focus to findbar to make prefill-with-selection work if the content is loaded in chrome process. Differential Revision: https://phabricator.services.mozilla.com/D89557 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=582459 gecko-commit: dff2fd52da6c98f5f92c08cf5c172a8dd44b0d87 gecko-reviewers: mikedeboer, NeilDeakin, hsivonen, jaws 
diff --git a/focus/iframe-activeelement-after-focusing-out-iframes.html b/focus/iframe-activeelement-after-focusing-out-iframes.html new file mode 100644 index 0000000..832b267 --- /dev/null +++ b/focus/iframe-activeelement-after-focusing-out-iframes.html 
@@ -0,0 +1,50 @@ +<!doctype html> +<meta charset=utf-8> +<title>iframe activeElement after focusing out iframe</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +function waitForEvent(target, event, checkFn) { + return new Promise(resolve => { + target.addEventListener(event, e => { + if (checkFn && !checkFn(e)) { + return; + } + resolve(); + }, { once: true }); + }); +} + +function focusTopLevel(w) { + w.postMessage("focus", "*"); +} + +async function getLog(w) { + let log = ""; + step_timeout(function() { + w.postMessage("getlog", "*"); + }, 0); + await waitForEvent(window, "message", (e) => { + log = e.data; + return true; + }); + return log; +} + +async function runTest(t, url) { + let w = window.open(url); + t.add_cleanup(() => { w.close(); }); + await waitForEvent(window, "message", e => e.data === "ready"); + focusTopLevel(w); + assert_equals(await getLog(w), 'outerlog:willfocusinput,windowfocus,didfocusinput,innerlog:willfocusinput,windowfocus,didfocusinput,activeElement:INPUT,windowblur,activeElement:BODY,'); +} + +promise_test(async t => { + await runTest(t, "support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html"); +}, "Check iframe activeElement after focusing out different site iframe"); + +promise_test(async t => { + await runTest(t, "support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html"); +}, "Check iframe activeElement after focusing out same site iframe"); + +</script> 
diff --git a/focus/support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html b/focus/support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html new file mode 100644 index 0000000..3fcebfc --- /dev/null +++ b/focus/support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html 
@@ -0,0 +1,34 @@ +<!doctype html> +<meta charset="utf-8"> +<title>iframe active element after focusing out different site iframes outer</title> +<input></input></br> +<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html"></iframe> +<script> +let outerlog = "outerlog:"; + +let input = document.querySelector("input"); +let iframe = document.querySelector("iframe"); +window.onmessage = function(e) { + if (e.data == "ready") { + opener.postMessage("ready", "*"); + } else if (e.data == "focus") { + outerlog += "willfocusinput,"; + input.focus(); + outerlog += "didfocusinput,"; + } else if (e.data == "getlog") { + iframe.contentWindow.postMessage("getlog", "*"); + } else { + opener.postMessage(outerlog + e.data, "*"); + } +}; + +window.onload = function() { + window.onfocus = function() { + outerlog += "windowfocus,"; + }; + + window.onblur = function() { + outerlog += "windowblur,"; + }; +}; +</script> 
diff --git a/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html b/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html new file mode 100644 index 0000000..a94af6b --- /dev/null +++ b/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html 
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>iframe active element inner document</title> +</head> +<body> +<h1>Inner</h1><br> +<input></input> +<script> +let innerlog = "innerlog:"; + +window.onmessage = function(e) { + if (e.data == "getlog") { + parent.postMessage(innerlog, "*"); + } +}; + +window.onfocus = function() { + innerlog += "windowfocus,"; +}; + +window.onblur = function() { + innerlog += "windowblur,"; + innerlog += "activeElement:" + document.activeElement.tagName + ","; +}; + +let input = document.querySelector("input"); +window.onload = function() { + innerlog += "willfocusinput,"; + input.focus(); + innerlog += "didfocusinput,"; + innerlog += "activeElement:" + document.activeElement.tagName + ","; + parent.postMessage("ready", "*"); +}; +</script> +</body> +</html> 
diff --git a/focus/support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html b/focus/support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html new file mode 100644 index 0000000..98399de --- /dev/null +++ b/focus/support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html 
@@ -0,0 +1,34 @@ +<!doctype html> +<meta charset="utf-8"> +<title>iframe active element after focusing out same site iframes outer</title> +<input></input></br> +<iframe src="iframe-activeelement-after-focusing-out-iframes-inner.html"></iframe> +<script> +let outerlog = "outerlog:"; + +let input = document.querySelector("input"); +let iframe = document.querySelector("iframe"); +window.onmessage = function(e) { + if (e.data == "ready") { + opener.postMessage("ready", "*"); + } else if (e.data == "focus") { + outerlog += "willfocusinput,"; + input.focus(); + outerlog += "didfocusinput,"; + } else if (e.data == "getlog") { + iframe.contentWindow.postMessage("getlog", "*"); + } else { + opener.postMessage(outerlog + e.data, "*"); + } +}; + +window.onload = function() { + window.onfocus = function() { + outerlog += "windowfocus,"; + }; + + window.onblur = function() { + outerlog += "windowblur,"; + }; +}; +</script>